home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / sm_unix.c < prev    next >
C/C++ Source or Header  |  1996-05-15  |  6KB  |  182 lines

  1. /*
  2.  * Program:    Subscription Manager (Unix based)
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    19 November 1992
  13.  * Last Edited:    15 May 1996
  14.  *
  15.  * Copyright 1996 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36.  
  37. #include "mail.h"
  38. #include "osdep.h"
  39. #include <sys/stat.h>
  40. #include "misc.h"
  41.  
  42. #define SUBSCRIPTIONFILE(t) sprintf (t,"%s/.mailboxlist",myhomedir ())
  43.  
  44. /* Subscribe to mailbox
  45.  * Accepts: mailbox name
  46.  * Returns: T on success, NIL on failure
  47.  */
  48.  
  49. long sm_subscribe (char *mailbox)
  50. {
  51.   int fd;
  52.   char *s,*t,*txt,tmp[MAILTMPLEN],tmpx[MAILTMPLEN];
  53.   struct stat sbuf;
  54.   long ret = T;
  55.   if (*mailbox == '/') {    /* coerce absolute file paths */
  56.     int i = strlen (s = myhomedir ());
  57.     if (!strncmp (mailbox,s,i) && mailbox[i] == '/') {
  58.       sprintf (tmpx,"~%s",mailbox + i);
  59.       mailbox = tmpx;        /* set as name to subscribe */
  60.     }
  61.   }
  62.   SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  63.   if ((fd = open (tmp,O_RDWR|O_CREAT,
  64.           (int) mail_parameters (NIL,GET_SUBPROTECTION,NIL))) >= 0) {
  65.     flock (fd,LOCK_EX);        /* wait for exclusive access */
  66.     fstat (fd,&sbuf);        /* get file size and read data */
  67.     read (fd,s = txt = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
  68.     s[sbuf.st_size] = '\0';    /* tie off string */
  69.     while (t = strchr (s,'\n')){/* for each line in database */
  70.       *t++ = '\0';        /* tie off string */
  71.       if (strcmp (s,mailbox)) s = t;
  72.       else {            /* oops, it's subscribed */
  73.     sprintf (tmp,"Already subscribed to mailbox %s",mailbox);
  74.     mm_log (tmp,ERROR);
  75.     ret = NIL;
  76.     break;
  77.       }
  78.     }
  79.     if (ret) {            /* append to end of file if OK */
  80.       lseek (fd,sbuf.st_size,L_SET);
  81.       sprintf (tmp,"%s\n",mailbox);
  82.       write (fd,tmp,strlen (tmp));
  83.       fsync (fd);        /* drop changes */
  84.     }
  85.     flock (fd,LOCK_UN);        /* release lock */
  86.     close (fd);            /* close off file */
  87.     fs_give ((void **) &txt);    /* free database */
  88.   }
  89.   else {
  90.     mm_log ("Can't create subscription database",ERROR);
  91.     ret = NIL;
  92.   }
  93.   return ret;            /* all done */
  94. }
  95.  
  96. /* Unsubscribe from mailbox
  97.  * Accepts: mailbox name
  98.  * Returns: T on success, NIL on failure
  99.  */
  100.  
  101. long sm_unsubscribe (char *mailbox)
  102. {
  103.   int fd;
  104.   char *s,*t,*txt,*end,tmp[MAILTMPLEN],tmpx[MAILTMPLEN];
  105.   struct stat sbuf;
  106.   long ret = NIL;
  107.   if (*mailbox == '/') {    /* coerce absolute file paths */
  108.     int i = strlen (s = myhomedir ());
  109.     if (!strncmp (mailbox,s,i) && mailbox[i] == '/') {
  110.       sprintf (tmpx,"~%s",mailbox + i);
  111.       mailbox = tmpx;        /* set as name to subscribe */
  112.     }
  113.   }
  114.   SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  115.   if ((fd = open (tmp,O_RDWR,NIL)) >= 0) {
  116.     flock (fd,LOCK_EX);        /* wait for exclusive access */
  117.     fstat (fd,&sbuf);        /* get file size and read data */
  118.     read (fd,s = txt = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
  119.                 /* tie off string */
  120.     *(end = s + sbuf.st_size) = '\0';
  121.     while (t = strchr (s,'\n')){/* for each line in database */
  122.       *t++ = '\0';        /* temporarily tie off string */
  123.       if (strcmp (s,mailbox)) {    /* match? */
  124.     t[-1] = '\n';        /* no, restore newline */
  125.     s = t;            /* try next subscription */
  126.       }
  127.       else {            /* cancel subscription */
  128.     if (t != end) memcpy (s,t,1 + end - t);
  129.     end -= t - s;        /* calculate new end of database */
  130.     ret = T;        /* note cancelled a subscription */
  131.       }
  132.     }
  133.     if (ret) {            /* found any? */
  134.       lseek (fd,0,L_SET);    /* yes, seek to start of file and write new */
  135.       if (end != txt) write (fd,txt,end - txt);
  136.       ftruncate (fd,end - txt);    /* tie off file */
  137.       fsync (fd);        /* drop changes */
  138.     }
  139.     else {            /* subscription not found */
  140.       sprintf (tmp,"Not subscribed to mailbox %s",mailbox);
  141.       mm_log (tmp,ERROR);    /* error if at end */
  142.     }
  143.     flock (fd,LOCK_UN);        /* release lock */
  144.     close (fd);            /* close off file */
  145.     fs_give ((void **) &txt);    /* free database */
  146.   }
  147.   else {
  148.     mm_log ("No subscriptions",ERROR);
  149.     ret = NIL;
  150.   }
  151.   return ret;            /* all done */
  152. }
  153.  
  154. /* Read subscription database
  155.  * Accepts: pointer to subscription database handle (handle NIL if first time)
  156.  * Returns: character string for subscription database or NIL if done
  157.  * Note - uses strtok() mechanism
  158.  */
  159.  
  160. char *sm_read (void **sdb)
  161. {
  162.   int fd;
  163.   char *s,*t,tmp[MAILTMPLEN];
  164.   struct stat sbuf;
  165.   if (!*sdb) {            /* first time through? */
  166.     SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  167.     if ((fd = open (tmp,O_RDWR,NIL)) >= 0) {
  168.       flock (fd,LOCK_SH);    /* let others know we're here */
  169.       fstat (fd,&sbuf);        /* get file size and read data */
  170.       read (fd,s = (char *) (*sdb = fs_get (sbuf.st_size + 1)),sbuf.st_size);
  171.       flock (fd,LOCK_UN);    /* release lock */
  172.       close (fd);        /* close file */
  173.       s[sbuf.st_size] = '\0';    /* tie off string */
  174.       if (t = strtok (s,"\n")) return t;
  175.     }
  176.   }
  177.                 /* subsequent times through database */
  178.   else if (t = strtok (NIL,"\n")) return t;
  179.   fs_give (sdb);        /* free database */
  180.   return NIL;            /* all done */
  181. }
  182.